﻿using System.Web.Mvc;
using EPiAbstractions;
using EPiAbstractions.Filters;
using EPiMVC.Routing;
using EPiServer.Core;
using EPiServer.Security;

namespace EPiMVC.Controllers
{
    public abstract class EPiServerControllerBase<T> : Controller where T : PageData
    {
        public EPiServerControllerBase() {}

        public EPiServerControllerBase(IDataFactoryFacade dataFactory, IFilterForVisitorFacade filterForVisitor, IFilterAccessFacade filterAccess)
        {
            this.dataFactory = dataFactory;
            this.filterForVisitor = filterForVisitor;
            this.filterAccess = filterAccess;
        }

        private IDataFactoryFacade dataFactory;
        protected IDataFactoryFacade DataFactory
        {
            get
            {
                if (dataFactory == null)
                    dataFactory = DataFactoryFacade.Instance;

                return dataFactory;
            }
        }

        private IFilterForVisitorFacade filterForVisitor;
        protected IFilterForVisitorFacade FilterForVisitor
        {
            get
            {
                if (filterForVisitor == null)
                    filterForVisitor = FilterForVisitorFacade.Instance;

                return filterForVisitor;
            }
        }

        private IFilterAccessFacade filterAccess;
        protected IFilterAccessFacade FilterAccess
        {
            get
            {
                if (filterAccess == null)
                    filterAccess = FilterAccessFacade.Instance;

                return filterAccess;
            }
        }

        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (!FilterAccess.QueryDistinctAccessEdit(CurrentPage, RequiredAccessLevel()))
            {
                filterContext.Result = new HttpUnauthorizedResult();
                return;
            }
            
            base.OnAuthorization(filterContext);
        }

        protected virtual AccessLevel RequiredAccessLevel()
        {
            return AccessLevel.Read;
        }

        private T currentPage;

        public T CurrentPage 
        { 
            get
            {
                if (currentPage == null)
                {
                    PageReference currentPageReference =
                        (PageReference)
                        ControllerContext.RequestContext.RouteData.Values[EPiServerRoute.CurrentPageReferenceKey];
                    currentPage = (T)EPiServer.DataFactory.Instance.GetPage(currentPageReference); 
                }

                return currentPage;    
            }

            set
            {
                currentPage = value;
            }
        }
    }
}
